package avicit.bdp.dds.api.controller;

import avicit.bdp.dds.apc.dto.ResUploadDto;
import avicit.bdp.dds.api.service.DdsResourceService;
import avicit.bdp.dds.dao.entity.Resource;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.core.rest.msg.ResponseMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 资源管理REST接口
 */
@RestController
@Api(tags = "资源管理REST接口")
@RequestMapping("/api/bdp/dds/resource")
public class ResourceRest {

    private static final Logger logger = LoggerFactory.getLogger(ResourceRest.class);
    @Autowired
    private DdsResourceService resourceService;
    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 查询目录树形展示
     */
    @ApiOperation(value = "查询文件夹树形展示")
    @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String")
    @GetMapping("/getTree")
    public ResponseMsg<List<Resource>> getTree(@RequestParam String projectId) {
        ResponseMsg<List<Resource>> responseMsg = new ResponseMsg<>();
        //查询不带文件的树
        List<Resource> result = resourceService.findResourceTree(projectId, false);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 查询文件/目录树形展示
     */
    @ApiOperation(value = "查询文件夹树形展示")
    @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String")
    @GetMapping("/getFileTree")
    public ResponseMsg<List<Resource>> getFileTree(@RequestParam String projectId) {
        ResponseMsg<List<Resource>> responseMsg = new ResponseMsg<>();
        List<Resource> result = resourceService.findResourceTree(projectId, true);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 查询文件夹树形展示
     */
    @ApiOperation(value = "查询文件夹树形展示")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "显示类型", dataType = "String")
    })
    @GetMapping("/getResourceTree")
    public ResponseMsg<List<Resource>> getResourceTree(@RequestParam String projectId,
                                                       @RequestParam String type) {
        ResponseMsg<List<Resource>> responseMsg = new ResponseMsg<>();
        boolean flag = false;
        //是否显示文件，还是只显示目录
        if (type.equalsIgnoreCase("file")) {
            flag = true;
        }
        List<Resource> result = resourceService.findResourceTree(projectId, flag);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 新增目录/文件
     */
    @PostMapping("/insertResource")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名称", dataType = "String"),
            @ApiImplicitParam(name = "pid", value = "父id", dataType = "String"),
            @ApiImplicitParam(name = "remark", value = "备注", dataType = "String"),
            @ApiImplicitParam(name = "file", value = "文件", dataType = "MultipartFile"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String"),
            @ApiImplicitParam(name = "directory", value = "是否目录", dataType = "Int")
    })
    @ApiOperation(value = "新增目录/文件")
    public ResponseMsg<String> insertResource(String name, String pid, String remark,
                                              MultipartFile file, String projectId, int directory) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(resourceService.insertForDirectory(name, pid, remark, file, projectId, directory));
        return responseMsg;
    }

    /**
     * 修改目录/文件
     */
    @PostMapping("/updateResource")
    @ApiOperation(value = "修改目录/文件")
    public ResponseMsg<String> updateResource(@RequestBody Resource resource) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        resourceService.updateForDirectory(resource);
        return responseMsg;
    }


    /**
     * 删除目录/文件
     */
    @ApiOperation(value = "按主键单条删除")
    @ApiImplicitParam(name = "id", value = "id", dataType = "String",  paramType = "body", required = true)
    @PostMapping("/deleteResource")
    public ResponseMsg<Integer> deleteResource(@ApiIgnore @RequestBody Map<String, String> queryMap) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        resourceService.deleteResource(queryMap.get("id"));
        return responseMsg;
    }

    /**
     * 判断资源/目录名称是否重复（同一层级）
     */
    @ApiOperation(value = "判断资源/目录名称是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "String",  paramType = "body"),
            @ApiImplicitParam(name = "name", value = "名称", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "pid", value = "父节点id", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String", paramType = "body"),
    })
    @PostMapping("/isSameName")
    public ResponseMsg<Boolean> isSameName(@ApiIgnore @RequestBody Map<String, Object> queryMap) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        String id = MapUtils.getString(queryMap, "id", "");
        String name = MapUtils.getString(queryMap, "name", "");
        String pid = MapUtils.getString(queryMap, "pid", "");
        String projectId = MapUtils.getString(queryMap, "projectId", "");
        Boolean flag = resourceService.isSameName(id, name, pid, projectId);
        responseMsg.setResponseBody(flag);
        return responseMsg;
    }

    /**
     * 查询右侧文件数据
     */
    @ApiOperation(value = "查询右侧文件数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "directoryId", value = "目录ID", dataType = "String"),
            @ApiImplicitParam(name = "projectId", value = "项目ID", dataType = "String"),
            @ApiImplicitParam(name = "keyWords", value = "查询关键字", dataType = "String"),
            @ApiImplicitParam(name = "pageNo", value = "当前页", dataType = "Int"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "Int")
    })
    @GetMapping("/getList")
    public ResponseMsg<QueryRespBean<Resource>> getList(
            @RequestParam String directoryId,
            @RequestParam String projectId,
            @RequestParam(required = false) String keyWords,
            @RequestParam(defaultValue = "1", required = false) Integer pageNo,
            @RequestParam(defaultValue = "10", required = false) Integer pageSize) {

        ResponseMsg<QueryRespBean<Resource>> responseMsg = new ResponseMsg<>();
        QueryRespBean<Resource> result = resourceService.getList(directoryId, projectId, keyWords, pageNo, pageSize);
        valueConvert(result.getResult());
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     *
     * @param resourceList 资源列表
     */
    private void valueConvert(List<Resource> resourceList) {
        //循环组装请求数据
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (Resource resource : resourceList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, resource.getCreatedBy());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (Resource resource : resourceList) {
                resource.setUsername(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                        resource.getCreatedBy()));
            }
        }
    }


    /**
     * 下载资源文件
     */
    @ApiOperation(value = "下载文件")
    @ApiImplicitParam(name = "resourceId", value = "资源id", dataType = "String")
    @GetMapping("/downloadFile")
    public void downloadFile(@RequestParam String resourceId, HttpServletResponse response) {
        this.resourceService.downloadFile(resourceId, response);
    }


    /**
     * 查询判读文件列表
     */
    @ApiOperation(value = "查询判读文件列表")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "项目空间ID", name = "projectId", dataType = "String"),
            @ApiImplicitParam(value = "目录ID", name = "directoryId", dataType = "String"),
            @ApiImplicitParam(value = "文件名称", name = "name", dataType = "String"),
            @ApiImplicitParam(value = "状态", name = "status", dataType = "Int"),
            @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int"),
            @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int")
    })
    @GetMapping("/getFileResList")
    public ResponseMsg<QueryRespBean<Resource>> getFileResList(@RequestParam String projectId,
                                                               @RequestParam(required = false) String directoryId,
                                                               @RequestParam(required = false) String name,
                                                               @RequestParam(required = false) Integer status,
                                                               @RequestParam(defaultValue = "1") Integer pageNo,
                                                               @RequestParam(defaultValue = "10") Integer pageSize) throws Exception {
        ResponseMsg<QueryRespBean<Resource>> responseMsg = new ResponseMsg<>();
        QueryRespBean<Resource> queryRespBean = resourceService.getFileResList(projectId, directoryId, name, status, pageNo, pageSize);
        responseMsg.setResponseBody(queryRespBean);
        return responseMsg;
    }

    @ApiOperation(value = "文件上传")
    @PostMapping("/uploadFileRes")
    public ResponseMsg<String> uploadFileRes(ResUploadDto resUploadDto,
                                             HttpServletResponse response) throws Exception {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        long startTime = System.currentTimeMillis();

        try {
            resourceService.uploadFileRes(resUploadDto);
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            responseMsg.setErrorDesc(e.getMessage());
            logger.error(e.getMessage(), e);
        }

        long endTime = System.currentTimeMillis();
        logger.info("上传文件{}--{}/{}，开始时间：{}，结束时间：{}，耗时：{}", resUploadDto.getFile().getOriginalFilename(),
                resUploadDto.getChunk(), resUploadDto.getChunks(), startTime, endTime, endTime - startTime);

        return responseMsg;
    }

    @ApiOperation(value = "删除资源")
    @DeleteMapping("/deleteFileRes")
    public ResponseMsg<Boolean> deleteFileRes(@RequestBody Resource resource) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(resourceService.deleteFileRes(resource.getId()));
        return responseMsg;
    }

    @ApiOperation(value = "重命名")
    @PostMapping("/renameFileRes")
    public ResponseMsg<Boolean> renameFileRes(@RequestBody Resource resource) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        resourceService.renameFileRes(resource);
        responseMsg.setResponseBody(true);
        return responseMsg;
    }

    @ApiOperation(value = "重新上传")
    @PostMapping("/reupload")
    public ResponseMsg<String> reupload(ResUploadDto resUploadDto,
                                        HttpServletResponse response) throws Exception {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        long startTime = System.currentTimeMillis();

        try {
            resourceService.reUpload(resUploadDto);
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            responseMsg.setErrorDesc(e.getMessage());
            logger.error(e.getMessage(), e);
        }

        long endTime = System.currentTimeMillis();
        logger.info("上传文件{}--{}/{}，开始时间：{}，结束时间：{}，耗时：{}", resUploadDto.getFile().getOriginalFilename(),
                resUploadDto.getChunk(), resUploadDto.getChunks(), startTime, endTime, endTime - startTime);

        return responseMsg;
    }

    @ApiOperation(value = "重新计算")
    @PostMapping("/recompute")
    public ResponseMsg<Boolean> recompute(@RequestBody Resource resource) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        resourceService.recompute(resource.getId());
        responseMsg.setResponseBody(true);
        return responseMsg;
    }

    @ApiOperation(value = "停止计算")
    @PostMapping("/stopCompute")
    public ResponseMsg<Boolean> stopCompute(@RequestBody Resource resource) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        resourceService.stopCompute(resource.getId());
        responseMsg.setResponseBody(true);
        return responseMsg;
    }

}
